<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>
    
    字符串的指针与指向字符串的指针变量 - DSRBLOG
    
  </title>
  

  
  
  <link href="atom.xml" rel="alternate" title="DSRBLOG" type="application/atom+xml">
  <link rel="stylesheet" href="asset/css/style.min.css">
  <link rel="stylesheet" href="asset/css/doc.css">
  <script src="asset/app.js"></script>


</head>

<body> <section class="ct-body">
	<div class="container">
		<div class="columns is-variable bd-klmn-columns is-4 is-centered">
			<div class="column is-four-fifths">
				<div class="post-body single-content">
					
					<h1 class="title">
						字符串的指针与指向字符串的指针变量
					</h1>


					<div class="media">
						
						
						<div class="media-content">
							<div class="content">
								<p>
									<span class="date">2022/01/19 21:25 下午</span>
									

									

									<br />
									<span class="tran-tags">Tags:</span>&nbsp;
									
									<a class="tag is-link is-light">#C语言</a>
									

								</p>
							</div>
						</div>

					</div>
				</div>
				<article class="markdown-body single-content">
					<h2><a id="%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E8%A1%A8%E8%BE%BE%E5%BD%A2%E5%BC%8F" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>字符串的表达形式</h2>
<h3><a id="%EF%BC%88%E4%B8%80%EF%BC%89%E7%94%A8%E5%AD%97%E7%AC%A6%E6%95%B0%E7%BB%84%E5%AD%98%E6%94%BE%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E7%84%B6%E5%90%8E%E8%BE%93%E5%87%BA%E8%AF%A5%E5%AD%97%E7%AC%A6%E4%B8%B2" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>（一）用字符数组存放一个字符串，然后输出该字符串</h3>
<pre class="line-numbers"><code class="language-c">int main()
{
    // string可存放的字符个数为字符数+1（有\0存在）
    char string[] = &quot;I love China!&quot;;
    printf(&quot;%s\n&quot;, string);
    return 0;
}
</code></pre>
<ul>
<li>I love China!是字符串常量，字符串常量在内存当中占用一段连续的空间</li>
<li>char存储的是与字符串常量相同的字符</li>
</ul>
<h3><a id="%EF%BC%88%E4%BA%8C%EF%BC%89%E7%94%A8%E5%AD%97%E7%AC%A6%E6%8C%87%E9%92%88%E6%8C%87%E5%90%91%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>（二）用字符指针指向一个字符串</h3>
<pre class="line-numbers"><code class="language-c">int main()
{
    char *string = &quot;I love China!&quot;; 
    printf(&quot;%s\n&quot;, string);
    return 0;
}
</code></pre>
<ul>
<li>I love China!是字符串常量，字符串常量在内存当中占用一段连续的空间</li>
<li>char *只能存储一个字符的地址，存储的是字符串常量的首字符地址</li>
</ul>
<h3><a id="%E5%8C%BA%E5%88%AB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>区别</h3>
<pre class="line-numbers"><code class="language-c">int main()
{
    char a[] = &quot;abc&quot;;
    char *p = &quot;123&quot;;

    printf(&quot;a = %s\n&quot;, a);
    printf(&quot;p = %s\n&quot;, p);
    return 0;
}
</code></pre>
<ul>
<li><em>字符串常量</em><code>abc</code>和<em>字符数组</em><code>a[]</code>各占用一个存储空间，并分别存储相同的内容</li>
<li><em>字符串常量</em><code>123</code>本身占有存储空间，<em>字符指针</em><code>p</code>只存储字符串常量的地址<br />
 </li>
<li><code> printf()</code>第一次输出的是<code>a[]</code>内存储的字符</li>
<li><code> printf()</code>第二次输出的是<code>p</code>指向的字符串常量的字符</li>
</ul>
<h2><a id="%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8C%87%E9%92%88%E4%BD%9C%E4%B8%BA%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>字符串指针作为函数参数</h2>
<h3><a id="%E4%BE%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>例</h3>
<p>用函数调用实现字符串的复制</p>
<pre class="line-numbers"><code class="language-c">#include &lt;stdio.h&gt;

void mycopy(char from[], char to[]);

int main()
{
    char *a = &quot;abc123&quot;;
    char b[10];
    mycopy(a, b);
    puts(b);

    return 0;
}
</code></pre>
<h4><a id="%E6%96%B9%E6%B3%95%E4%B8%80%EF%BC%88to-i-from-i%EF%BC%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>方法一（to[i] = from[i]）</h4>
<p>以数组名为实参和形参，虽然数组名不同，但其实是同一个存储单元</p>
<pre class="line-numbers"><code class="language-c">void mycopy(char from[], char to[])
{
    int i = 0;
    while (from[i] != '\0')
    {
        to[i] = from[i];
        i++;
    }
    to[i] = '\0';
}
</code></pre>
<h4><a id="%E6%96%B9%E6%B3%95%E4%BA%8C%EF%BC%88to-from%EF%BC%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>方法二（*to = *from）</h4>
<p>以数组名为实参，指针变量为形参，对指针变量进行自加运算</p>
<pre class="line-numbers"><code class="language-c">void mycopy(char *from, char *to)
{
    while (*from != '\0')
    {
        *to = *from;
        to++;
        from++;
    }
    *to = '\0';
}
</code></pre>
<h4><a id="%E6%96%B9%E6%B3%95%E4%B8%89%EF%BC%88to-from-0%EF%BC%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>方法三（(*to = *from)!='\0'）</h4>
<p>在方法二的基础上，在循环条件内进行自加运算和判断，可读性较差</p>
<pre class="line-numbers"><code class="language-c">void mycopy(char *from, char *to)
{
    while ((*to = *from) != '\0')
    {
        to++;
        from++;
    }
}
</code></pre>
<h4><a id="%E6%96%B9%E6%B3%95%E5%9B%9B%EF%BC%88to-from-0%EF%BC%89" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>方法四（(*to++=*from++)!='\0'）</h4>
<p>在方法二的基础上，在循环条件内进行自加运算、赋值运算和判断，可读性最差</p>
<pre class="line-numbers"><code class="language-c">void mycopy(char *from, char *to)
{
    while ((*to++ = *from++) != '\0');
}
</code></pre>
<h2><a id="%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8C%87%E9%92%88%E5%8F%98%E9%87%8F%E4%B8%8E%E5%AD%97%E7%AC%A6%E6%95%B0%E7%BB%84%E7%9A%84%E5%8C%BA%E5%88%AB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>字符串指针变量与字符数组的区别</h2>
<ul>
<li>
<p>字符数组由若干个元素组成，每个元素中存放一个字符，而字符指针变量中存放的是字符数组的首地址，不是将字符串放入字符指针变量</p>
</li>
<li>
<p>若定义了一个指针变量，并使它指向一个字符串，就可以用下标形式引用指针变量所指的字符串中的字符</p>
</li>
</ul>
<pre class="line-numbers"><code class="language-c">int main()
{
    char *a = &quot;Hello world!&quot;; // 定义一个字符指针变量，并指向字符串常量&quot;Hello world!&quot;
    int i;
    for (i = 0; a[i] != '\0'; i++) // 当指针指向的元素为'\0'时结束循环
        printf(&quot;%c&quot;, a[i]); // 通过下标形式输出当前元素存储的字符
    return 0;
}
</code></pre>
<h3><a id="%E5%88%86%E9%85%8D%E7%9A%84%E5%AD%98%E5%82%A8%E5%8D%95%E5%85%83%E4%B8%8D%E5%90%8C" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>分配的存储单元不同</h3>
<ul>
<li>
<p>定义字符数组时，在编译时会自动分配一个内存单元，每一个数据元素都有确定的地址</p>
</li>
<li>
<p>定义字符指针变量时，只给指针分配内存单元，其中只能存放一个字符串常量的首字符地址，</p>
</li>
</ul>
<p><strong>注意：</strong> <code>scanf()</code>语句只能用于字符数组，不能用于字符指针</p>
<h3><a id="%E8%B5%8B%E5%80%BC%E6%96%B9%E5%BC%8F%E4%B8%8D%E5%90%8C" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>赋值方式不同</h3>
<ul>
<li>字符数组只能在声明字符数组的同时进行初始化，否则只能对各个元素逐一赋值，或通过字符串处理函数strcpy(a,字符串常量)进行复制，如：</li>
</ul>
<pre class="line-numbers"><code class="language-c">char a[20] = &quot;Hello world!&quot;;
</code></pre>
<p><strong>不能等价于</strong></p>
<pre class="line-numbers"><code class="language-c">char a[20];
a[] = &quot;Hello world!&quot;;
</code></pre>
<ul>
<li>字符指针变量可以在声明字符指针变量之后，再对整个字符指针赋值，如：</li>
</ul>
<pre class="line-numbers"><code class="language-c">char *a = &quot;Hello world&quot;;
</code></pre>
<p><strong>等价于</strong></p>
<pre class="line-numbers"><code class="language-c">char *a;
a = &quot;Hello world!&quot;;
</code></pre>

				</article>
				<div class="comments-wrap">
					<div class="share-comments">
						

						

						
					</div>
				</div><!-- end comments wrap -->
			</div>
		</div><!-- end columns -->
	</div><!-- end container -->
</section>  














<script src="asset/prism.js"></script>









</body>

</html>